/*
题目: 设计食物评分系统
设计一个支持下述操作的食物评分系统：
    修改 系统中列出的某种食物的评分。
    返回系统中某一类烹饪方式下评分最高的食物。
实现 FoodRatings 类：
    FoodRatings(String[] foods, String[] cuisines, int[] ratings) 初始化系统。食物由 foods、cuisines 和 ratings 描述，长度均为 n 。
    foods[i] 是第 i 种食物的名字。
    cuisines[i] 是第 i 种食物的烹饪方式。
    ratings[i] 是第 i 种食物的最初评分。

void changeRating(String food, int newRating) 修改名字为 food 的食物的评分。
String highestRated(String cuisine) 返回指定烹饪方式 cuisine 下评分最高的食物的名字。如果存在并列，返回 字典序较小 的名字。
https://leetcode.cn/contest/weekly-contest-303/problems/design-a-food-rating-system/
 */
class FoodRatings {
    String[] foods = null;
    String[] cuisines = null;
    int[] ratings = null;

    Map<String, Integer> map = new HashMap<> (); //获取这个食物的下标
    Map<String, TreeSet<Integer> > rank = new HashMap<> ();  //根据烹饪方式, 得到下标, 根据下标的评分排名

    public FoodRatings(String[] foods, String[] cuisines, int[] ratings) {
        this.foods = foods;
        this.cuisines = cuisines;
        this.ratings = ratings;

        //初始化
        for (int i = 0; i < foods.length; i++) {
            map.put(foods[i], i); //映射食物和下标

            if (! rank.containsKey(cuisines[i])) {  //如果不包含这个烹饪方式
                rank.put(cuisines[i], new TreeSet<> (new Comparator<Integer> (){
                    public int compare(Integer o1, Integer o2) {
                        if (ratings[o1] != ratings[o2]) {
                            return ratings[o2] - ratings[o1];  //如果评分不相等, 那就根据评分降序
                        } else {
                            return foods[o1].compareTo(foods[o2]);  //比较字符串的方法
                        }
                    }
                }));
            }
            rank.get(cuisines[i]).add(i);
        }
    }

    public void changeRating(String food, int newRating) {
        int index = map.get(food); //获得这个食物的下标
        String cuisine = cuisines[index];  //获得这个事务的烹饪方式
        TreeSet<Integer> cur = rank.get(cuisine); //获得这个烹饪方式的排行

        cur.remove(index);
        ratings[index] = newRating;
        cur.add(index);
    }

    public String highestRated(String cuisine) {
        int index = rank.get(cuisine).first();
        return foods[index];
    }
}